<?
/**
 * This file is part of XNAT light.
 *
 * XNAT light is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * XNAT light is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with XNAT light.  If not, see <http://www.gnu.org/licenses/>.
 */
namespace NRG\Xnat;

use NRG\Xnat\Xnat as Xnat;
use NRG\Exceptions as Exceptions;
use NRG\Framework as Framework;
use NRG\Xnat\XObject as XObject;
use NRG\Xnat\Scan as Scan;
use NRG\Database\Mappers as Mappers;

/**
 * XNAT MR Session model
 *
 * @package NRG\Xnat
 */
class MrSession extends XObject
{
    /**
     * MR Session Accession ID
     * 
     * @var string
     */
    protected $_id;
 
    /**
     * MR Session label
     *
     * @var string
     */
    protected $_label;

    /**
     * Coil
     *
     * @var string
     */
    protected $_coil;

    /**
     * Session date
     *
     * @var string
     */
    protected $_date;
    
    /**
     * Stabilization method
     *
     * @var string
     */
    protected $_stabilization;

    /**
     * Field strength
     *
     * @var string
     */
    protected $_fieldStrength;
    
    /**
     * Marker
     *
     * @var string
     */
    protected $_marker;

    /**
     * DICOM patient name
     * 	
     * @var string
     */
    protected $_patientName;
    
    /**
     * Scans
     *
     * @var array \NRG\Xnat\Scan
     */
    protected $_scans;

    /**
     * Assessors
     *
     * @var array (string, NRG/Xnat/MrAssessor)
     */
    protected $_assessors;
    
    /**
     * Archive directory
     *
     * @var string
     */
    protected $_archivePath;

    /**
     * Archived status
     *
     * @var boolean
     */
    protected $_isArchived;
    
    /**
     * MR Session parent ID
     *
     * @var string
     */
    protected $_parentID;

    /**
     * MR Session parent
     *
     * @var NRG\Xnat\Subject
     */
    protected $_parent;

    /**
     * Constructor
     */
    public function __construct()
    {
	parent::__construct();

	$this->_scans = array();
	$this->_assessors = array();
	$this->_isArchived = true;
    }

    /**
     * Set Accession ID
     *
     * @param string $id
     */
    public function setID($id=null)
    {
	$this->_id = $id;
    }

    /**
     * Set coil
     *
     * @param string $coil
     */
    public function setCoil($coil=null)
    {
	$this->_coil = $coil;
    }

    /**
     * Set date
     *
     * @param string $date
     */
    public function setDate($date=null)
    {
	$this->_date = $date;
    }

    /**
     * Set field strength
     *
     * @param string $fieldStrength
     */
    public function setFieldStrength($fieldStrength=null)
    {
	$this->_fieldStrength = $fieldStrength;
    }

    /**
     * Set marker
     *
     * @param string $marker
     */
    public function setMarker($marker=null)
    {
	$this->_marker = $marker;
    }

    /**
     * Set stabilization method
     *
     * @param string $stabilization
     */
    public function setStabilization($stabilization=null)
    {
	$this->_stabilization = $stabilization;
    }

    /**
     * Set DICOM patient name
     *
     * @param string $patientName
     */
    public function setPatientName($patientName=null)
    {
	$this->_patientName = $patientName;
    }

    /**
     * Set label
     *
     * @param string $label
     */
    public function setLabel($label=null)
    {
	$this->_label = $label;
    }

    /**
     * Access session label
     *
     * @return string
     */
    public function getLabel()
    {
	return $this->_label;
    }

    /**
     * Get scanner coil
     *
     * @return string
     */
    public function getCoil()
    {
	return $this->_coil;
    }

    /**
     * Get MR Session acquisition date
     * 
     * @return string
     */
    public function getDate()
    {
	return $this->_date;
    }

    /**
     * Access DICOM patient name
     *
     * @return string
     */
    public function getPatientName()
    {
	return $this->_patientName;
    }

    /**
     * Access stabilization
     *
     * @return string
     */
    public function getStabilization()
    {
	return $this->_stabilization;
    }

    /**
     * Access MR Session Accession ID
     *
     * @return string
     */
    public function getID()
    {
	return $this->_id;
    }

    /*
     * Retrieve the session project
     *
     * @return NRG\Xnat\Project
     * @throws Exception
     */

    public function getProject()
    {
	if($this->_parent === null)
	    $this->getParent();

	return $this->_parent->getProject();
    }

    /**
     * Access archive path
     *
     * @return string
     */
    public function getArchivePath()
    {
	if($this->_parent === null)
	    $this->getParent();

	return $this->_parent->getProject()->getArchivePath() . "/arc001/" . $this->_label;
    }

    /**
     * Add a scan to the scans array
     *
     * @param NRG\Xnat\Scan $scan
     */
    public function addScan(Scan $scan=null)
    {
	if($scan == null)
	    throw new Framework\Exceptions\IllegalArgumentException("Scan cannot be null");

	$this->_scans[$scan->getScanNumber()] = $scan;
    }

    /**
     * Get scans array
     *
     * @return array
     */
    public function getScans()
    {
	return $this->_scans;
    }

    /**
     * Set MR Session archived status
     *
     * @param boolean $status
     */
    public function setArchived($status=true)
    {
	if(!is_bool($status))
	    throw new Framework\Exceptions\IllegalArgumentException("Status must be boolean");

	$this->_isArchived = $status;
    }

    /**
     * Check archived status of MR Session
     *
     * @return boolean
     */
    public function isArchived()
    {
	return $this->_isArchived;
    }

    /**
     * Add an assessor ID
     *
     * @param string $id
     */
    public function addAssessor($key=null, MrAssessor $assessor=null)
    {
	if($key == null)
	    throw new Framework\Exceptions\IllegalArgumentException("Key cannot be null");

	if(array_key_exists($key, $this->_assessors))
	    throw new Exceptions\KeyExistsException($key);
	else
	    $this->_assessors[$key] = $assessor;
    }

    /**
     * Access an assessor by ID
     *
     * @param string $key
     * @return NRG\Xnat\MrAssessor
     */
    public function getAssessor($key=null)
    {
	if(array_key_exists($key, $this->_assessors))
	{
	    if($this->_assessors[$key] === null)
	    {
		$mapper = new Mappers\MrAssessor();
		$this->_assessors[$key] = $mapper->getAssessor($key);
	    }

	    return $this->_assessors[$key];
	}
	else
	    throw new Framework\Exceptions\IndexOutOfBoundsException($key);
    }

    /**
     * Set parent ID
     *
     * @var string
     */
    public function setParentID($id=null)
    {
	if(!is_string($id))
	    throw new Framework\Exceptions\IllegalArgumentException("Parent ID must be a string");

	if($id == "")
	    throw new Framework\Exceptions\IllegalArgumentException("Parent ID cannot be null");

	$this->_parentID = $id;
    }

    /**
     * Access MR Session parent
     *
     * @return NRG\Xnat\Subject
     */
    public function getParent()
    {
	if($this->_parent === null)
	{
	    if($this->_parentID === null)
		throw new Exceptions\FieldNotSetException("Parent ID");

	    $mapper = new Mappers\Subject();
	    $this->_parent = $mapper->byId($this->_parentID);
	}

	return $this->_parent;
    }

    public function getAssessors()
    {
	foreach($this->_assessors as $key => $assessor)
	{
	    if($assessor === null)
		$this->getAssessor($key);
	}

	return $this->_assessors;
    }
}